﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;

namespace Kokomo.Controls
{
	public class TreemapItem : TreeViewItem
	{
		static TreemapItem()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(TreemapItem), new FrameworkPropertyMetadata(typeof(TreemapItem)));
		}

		public TreemapItem()
		{
			this.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
		}

		void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
		{
			this.RecalculateBranchSize();
		}

		protected override System.Windows.DependencyObject GetContainerForItemOverride()
		{
			return new TreemapItem();
		}
		protected override bool IsItemItsOwnContainerOverride(object item)
		{
			return item is TreemapItem;
		}

		protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
		{
			base.OnItemsChanged(e);

			this.RecalculateBranchSize();
		}

		private void RecalculateBranchSize()
		{
			this.IsLeaf = !this.HasItems;

			if (this.IsLeaf)
			{
				this.BranchSize = this.LeafSize;
			}
			else
			{
				float branchSize = 0;
				foreach (var item in this.Items)
				{
					object container = this.ItemContainerGenerator.ContainerFromItem(item);
					//object container = this.ItemContainerGenerator.ContainerFromIndex(0);
					TreemapItem treemapItemContainer = container as TreemapItem;
					if (treemapItemContainer == null) continue;
					branchSize += treemapItemContainer.BranchSize;
				}
				this.BranchSize = branchSize;
			}
		}

		public float LeafSize
		{
			get { return (float)GetValue(LeafSizeProperty); }
			set { SetValue(LeafSizeProperty, value); }
		}

		// Using a DependencyProperty as the backing store for LeafSize.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty LeafSizeProperty =
			DependencyProperty.Register("LeafSize", typeof(float), typeof(TreemapItem), new FrameworkPropertyMetadata(1.0F, OnLeafSizeChanged));

		private static void OnLeafSizeChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			((TreemapItem)target).OnLeafSizeChanged(e);
		}
		private void OnLeafSizeChanged(DependencyPropertyChangedEventArgs e)
		{
			this.RecalculateBranchSize();
			//if (this.IsLeaf)
			//{
			//    this.BranchSize = this.LeafSize;
			//}
		}

		public bool IsLeaf
		{
			get { return (bool)GetValue(IsLeafProperty); }
			private set { SetValue(IsLeafPropertyKey, value); }
		}

		// Using a DependencyProperty as the backing store for IsLeaf.  This enables animation, styling, binding, etc...
		private static readonly DependencyPropertyKey IsLeafPropertyKey =
			DependencyProperty.RegisterReadOnly("IsLeaf", typeof(bool), typeof(TreemapItem), new FrameworkPropertyMetadata(true));
		public static readonly DependencyProperty IsLeafProperty = IsLeafPropertyKey.DependencyProperty;

		internal float _branchSize;
		public float BranchSize
		{
			get { return this._branchSize; }
			private set { this._branchSize = value; }
		}

		//public double BranchSize
		//{
		//    get { return (double)GetValue(BranchSizeProperty); }
		//    internal set { SetValue(BranchSizePropertyKey, value); }
		//}

		//// Using a DependencyProperty as the backing store for BranchSize.  This enables animation, styling, binding, etc...
		//private static readonly DependencyPropertyKey BranchSizePropertyKey =
		//    DependencyProperty.RegisterReadOnly("BranchSize", typeof(double), typeof(TreemapItem), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsParentArrange | FrameworkPropertyMetadataOptions.AffectsParentMeasure, OnBranchSizeChanged));
		//public static readonly DependencyProperty BranchSizeProperty = BranchSizePropertyKey.DependencyProperty;

		static void OnBranchSizeChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			((TreemapItem)target).OnBranchSizeChanged(e);
		}
		protected virtual void OnBranchSizeChanged(DependencyPropertyChangedEventArgs e)
		{
			ItemsControl itemsControl =  ItemsControlFromItemContainer(this);
			TreemapItem owner = itemsControl as TreemapItem;
			if (owner != null)
			{
				owner.RecalculateBranchSize();
			}
		}
	}
}
